#!/usr/bin/env bash

# Read Slurm non-user accounts with sacctmgr and create an accounts config file
# Homepage: https://github.com/OleHolmNielsen/Slurm_tools/

# Syntax of the accounts config file is:
# account:parent:FairShare:Description[:Alias_group]
# The 5th field Alias_group is optional and must be added manually,
# it says that an account is an alias for the UNIX group Alias_group

# sacctmgr -snorp output is:
# Account|Descr|Org|Cluster|Par Name|User|Share|GrpJobs|GrpNodes|GrpCPUs|GrpMem|GrpSubmit|GrpWall|GrpCPUMins|MaxJobs|MaxNodes|MaxCPUs|MaxSubmitJobs|MaxWall|MaxCPUMins|QOS|Def QOS|
/usr/bin/sacctmgr -snorp show accounts format="Account,Description,Organization,Cluster,ParentName,User,Fairshare" | awk -F"|" '
function print_children(a, path)
{
	# a: account name
	# path: String describing the parent path leading to this account
	if (isarray(children[a])) {	# This account has children accounts
		if (a != "root") {	# Do not print the Slurm built-in root account
			print "###"
			print "### Parent account " path
			print account[a] ":" parent[a] ":" fairshare[a] ":" desc[a]
		}
		# Making a more readable list:
		# First print the accounts with no children, then those with children
		for (c in children[a]) {
			if (!isarray(children[c])) print_children(c, path "->" c)
		}
		for (c in children[a]) {
			if (isarray(children[c])) print_children(c, path "->" c)
		}
	} else	# Bottom-level accounts
		print account[a] ":" parent[a] ":" fairshare[a] ":" desc[a]
}
$6 == "" {	# Process all non-user accounts ($6 is empty)
	# Read list of existing accounts (parseable output)
	# Debug: print "Got account ", $0
	account[$1]	= $1
	desc[$1]	= $2
	ClusterName	= $4
	parent[$1]	= $5
	fairshare[$1]	= $7
	children[$5][$1] = $1
} END {
	print "###"
	print "### Slurm accounts for cluster " ClusterName
	print "###"
	print "### Syntax of the file is:"
	print "### account:parent:FairShare:Description"
	# Make a hierarchical printout starting at the "root" account
	print_children("root", "root")
}'
